package com.shlh.saas.service.facebook.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shlh.saas.entity.facebook.EsFacebookFields;
import com.shlh.saas.entity.facebook.FacebookUserEs;
import com.shlh.saas.entity.twitter.TwitterUserEs;
import com.shlh.saas.es.EsIndexInfo;
import com.shlh.saas.es.EsRestClient;
import com.shlh.saas.es.EsSearchRequest;
import com.shlh.saas.model.dto.FacebookQueryDTO;
import com.shlh.saas.service.facebook.FacebookEsService;

import lombok.extern.slf4j.Slf4j;

import org.elasticsearch.action.search.SearchResponse;

import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * Facebook Elasticsearch服务实现类
 *
 */
@Service
@Slf4j
public class FacebookEsServiceImpl implements FacebookEsService {

    @Override
    public Page<FacebookUserEs> queryFacebookUserList(FacebookUserEs req) {

        Page<FacebookUserEs> pageResult = new Page<>();
        EsSearchRequest esSearchRequest = createEsSearchRequest(req);
        SearchResponse searchResponse =
                EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);
        List<FacebookUserEs> facebookUserEsList = new LinkedList<>();
        SearchHits searchHits = null;
        if (searchResponse != null) {
            searchHits = searchResponse.getHits();
        }
        if (searchHits == null || searchHits.getHits() == null) {
            pageResult.setTotal(req.getTotal());
            pageResult.setSize(req.getSize());
            pageResult.setRecords(facebookUserEsList);
            return pageResult;
        }

        SearchHit[] hits = searchHits.getHits();
        log.info("🔍 ES查询调试 - 查询结果: 请求页码={}, 请求大小={}, ES返回条数={}, 总记录数={}",
                req.getCurrent(), req.getSize(), hits.length, searchHits.getTotalHits().value);

        int convertedCount = 0;
        int failedCount = 0;

        for (SearchHit hit : hits) {
            FacebookUserEs facebookUserEs = convertResult(hit);
            if (Objects.nonNull(facebookUserEs)) {
                facebookUserEsList.add(facebookUserEs);
                convertedCount++;
            } else {
                failedCount++;
                log.warn("🔍 ES查询调试 - 数据转换失败: hitId={}", hit.getId());
            }
        }

        log.info("🔍 ES查询调试 - 数据转换结果: 成功转换={}, 转换失败={}, 最终返回条数={}",
                convertedCount, failedCount, facebookUserEsList.size());

        // 当前页码
        pageResult.setCurrent(req.getCurrent());
        // 每页大小
        pageResult.setSize(req.getSize());
        pageResult.setRecords(facebookUserEsList);
        // 总记录数
        pageResult.setTotal(searchHits.getTotalHits().value);
        return pageResult;
    }

    @Override
    public Map<String, List<String>> queryFacebookUserMapList(FacebookUserEs req) {
        Map<String, List<String>> mapList = new HashMap<>();
        List<String> currentLocations = new ArrayList<>();
        List<String> hometowns = new ArrayList<>();
        List<String> relationshipStatuses = new ArrayList<>();
        List<String> workplaces = new ArrayList<>();
        Page<FacebookUserEs> pageResult = new Page();
        EsSearchRequest esSearchRequest = createEsSearchRequest(req);
        SearchResponse searchResponse =
                EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);
        SearchHits searchHits = null;
        if (searchResponse != null) {
            searchHits = searchResponse.getHits();
        }
        if (searchHits == null || searchHits.getHits() == null) {
            mapList.put("currentLocations", currentLocations);
            mapList.put("hometowns", hometowns);
            mapList.put("relationshipStatuses", relationshipStatuses);
            mapList.put("workplaces", workplaces);
            return mapList;
        }

        SearchHit[] hits = searchHits.getHits();
        log.debug("ES查询返回{}条结果", hits.length);

        for (SearchHit hit : hits) {
            FacebookUserEs facebookUserEs = convertResult(hit);
            if (Objects.nonNull(facebookUserEs)) {
                currentLocations.add(hit.getSourceAsMap().get(EsFacebookFields.WORKPLACE_CITY).toString());
                hometowns.add(hit.getSourceAsMap().get(EsFacebookFields.BIRTH_PLACE).toString());
                relationshipStatuses.add(hit.getSourceAsMap().get(EsFacebookFields.MARITAL_STATUS).toString());
                workplaces.add(hit.getSourceAsMap().get(EsFacebookFields.WORK_PLACE).toString());
            }
        }

        mapList.put("currentLocations", currentLocations);
        mapList.put("hometowns", hometowns);
        mapList.put("relationshipStatuses", relationshipStatuses);
        mapList.put("workplaces", workplaces);

        return mapList;
    }

    private EsIndexInfo getEsIndexInfo() {
        EsIndexInfo esIndexInfo = new EsIndexInfo();
        esIndexInfo.setClusterName("my-es");
//        esIndexInfo.setClusterName("elasticsearch");
        esIndexInfo.setIndexName("facebook_user");
        return esIndexInfo;
    }

    /**
     * 从Map直接转换为FacebookUserEs对象（用于Scroll查询）
     */
    private FacebookUserEs convertResultFromMap(Map<String, Object> sourceAsMap) {
        if (CollectionUtils.isEmpty(sourceAsMap)) {
            return null;
        }

        FacebookUserEs result = new FacebookUserEs();

        // 使用安全获取方法，避免空指针
        result.setMysqlId(getStringSafely(sourceAsMap, EsFacebookFields.MYSQL_ID));
        result.setUid(getStringSafely(sourceAsMap, EsFacebookFields.UID));
        result.setMysqlTable(getStringSafely(sourceAsMap, EsFacebookFields.MYSQL_TABLE));
        result.setEmail(getStringSafely(sourceAsMap, EsFacebookFields.EMAIL));
        result.setBirthPlace(getStringSafely(sourceAsMap, EsFacebookFields.BIRTH_PLACE));
        result.setGender(getStringSafely(sourceAsMap, EsFacebookFields.GENDER));
        result.setDocId(getStringSafely(sourceAsMap, EsFacebookFields.DOC_ID));
        result.setMaritalStatus(getStringSafely(sourceAsMap, EsFacebookFields.MARITAL_STATUS));
        result.setFirstName(getStringSafely(sourceAsMap, EsFacebookFields.FIRST_NAME));
        result.setLastName(getStringSafely(sourceAsMap, EsFacebookFields.LAST_NAME));
        result.setFullName(getStringSafely(sourceAsMap, EsFacebookFields.FULL_NAME));
        result.setPhoneNumber(getStringSafely(sourceAsMap, EsFacebookFields.PHONE_NUMBER));
        result.setWorkPlace(getStringSafely(sourceAsMap, EsFacebookFields.WORK_PLACE));
        result.setWorkplaceCity(getStringSafely(sourceAsMap, EsFacebookFields.WORKPLACE_CITY));

        log.debug("成功转换Facebook ES记录: mysqlId={}, mysqlTable={}", result.getMysqlId(), result.getMysqlTable());

        return result;
    }
    
    private FacebookUserEs convertResult(SearchHit hit) {
        Map<String, Object> sourceAsMap = hit.getSourceAsMap();
        if (CollectionUtils.isEmpty(sourceAsMap)) {
            return null;
        }

        FacebookUserEs result = convertResultFromMap(sourceAsMap);
        
        if (result != null) {
            // 处理评分（只有非Scroll查询才有评分）
            float rawScore = hit.getScore();
            BigDecimal score = BigDecimal.valueOf(rawScore)
                    .multiply(BigDecimal.valueOf(100.00))
                    .setScale(2, RoundingMode.HALF_UP);
            result.setScore(score);
        }

        return result;
    }

    // 安全获取字符串值
    private String getStringSafely(Map<String, Object> map, String key) {
        if (map == null || key == null) return null;
        Object value = map.get(key);
        return (value != null) ? value.toString() : null;
    }

    private EsSearchRequest createEsSearchRequest(FacebookUserEs facebookUserEs) {
        log.debug("创建ES查询请求: phoneNumber={}, workPlace={}, workplaceCity={}, birthPlace={},  contactMethod={}, fullName={}, firstName={}, lastName={}",
                facebookUserEs.getPhoneNumber(), facebookUserEs.getWorkPlace(),
                facebookUserEs.getWorkplaceCity(), facebookUserEs.getBirthPlace(),
                facebookUserEs.getContactMethod(), facebookUserEs.getFullName(),
                facebookUserEs.getFirstName(), facebookUserEs.getLastName());

        EsSearchRequest esSearchRequest = new EsSearchRequest();
        BoolQueryBuilder bq = new BoolQueryBuilder();

        if (facebookUserEs.getPhoneNumber() != null && !facebookUserEs.getPhoneNumber().isEmpty()) {
            MatchQueryBuilder phoneNumberQueryBuilder =
                    QueryBuilders.matchQuery(EsFacebookFields.PHONE_NUMBER, facebookUserEs.getPhoneNumber());
            bq.must(phoneNumberQueryBuilder);
        }

        if (facebookUserEs.getFirstName() != null && !facebookUserEs.getFirstName().isEmpty()) {
            MatchQueryBuilder firstNameQueryBuilder =
                    QueryBuilders.matchQuery(EsFacebookFields.FIRST_NAME, facebookUserEs.getFirstName());
            bq.must(firstNameQueryBuilder);
        }


        if (facebookUserEs.getLastName() != null && !facebookUserEs.getLastName().isEmpty()) {
            MatchQueryBuilder lastNameQueryBuilder =
                    QueryBuilders.matchQuery(EsFacebookFields.LAST_NAME, facebookUserEs.getLastName());
            bq.must(lastNameQueryBuilder);
        }

        if (facebookUserEs.getFullName() != null && !facebookUserEs.getFullName().isEmpty()) {
            MatchPhraseQueryBuilder fullNameQueryBuilder = QueryBuilders.matchPhraseQuery(
                    EsFacebookFields.FULL_NAME,
                    facebookUserEs.getFullName()
            ).boost(2);
            bq.must(fullNameQueryBuilder);
        }

        // 工作地点多值查询支持
        if (facebookUserEs.getWorkPlace() != null && !facebookUserEs.getWorkPlace().isEmpty()) {
            BoolQueryBuilder workPlaceBool = QueryBuilders.boolQuery();

            if (facebookUserEs.getWorkPlace().contains("、")) {
                // 多值查询：使用OR逻辑
                String[] workplaces = facebookUserEs.getWorkPlace().split("、");
                workPlaceBool.minimumShouldMatch(1);

                log.info("🔍 工作地点多值查询: 原始值={}, 拆分后={}", facebookUserEs.getWorkPlace(), String.join(",", workplaces));

                for (String workplace : workplaces) {
                    String trimmedWorkplace = workplace.trim();
                    if (!trimmedWorkplace.isEmpty()) {
                        MatchQueryBuilder workPlaceQuery =
                                QueryBuilders.matchQuery(EsFacebookFields.WORK_PLACE, trimmedWorkplace);
                        workPlaceBool.should(workPlaceQuery);
                        log.debug("🔍 添加工作地点查询条件: {}", trimmedWorkplace);
                    }
                }
            } else {
                // 单值查询
                MatchQueryBuilder workPlaceQuery =
                        QueryBuilders.matchQuery(EsFacebookFields.WORK_PLACE, facebookUserEs.getWorkPlace());
                workPlaceBool.should(workPlaceQuery);
                log.info("🔍 工作地点单值查询: {}", facebookUserEs.getWorkPlace());
            }

            bq.must(workPlaceBool);
        }

        if (facebookUserEs.getGender() != null && !facebookUserEs.getGender().isEmpty()) {
            MatchQueryBuilder genderQueryBuilder =
                    QueryBuilders.matchQuery(EsFacebookFields.GENDER, facebookUserEs.getGender());
            bq.must(genderQueryBuilder);
        }


        // 家乡多值查询支持
        if (facebookUserEs.getBirthPlace() != null && !facebookUserEs.getBirthPlace().isEmpty()) {
            BoolQueryBuilder birthPlaceBool = QueryBuilders.boolQuery();

            if (facebookUserEs.getBirthPlace().contains("、")) {
                // 多值查询：使用OR逻辑
                String[] birthPlaces = facebookUserEs.getBirthPlace().split("、");
                birthPlaceBool.minimumShouldMatch(1);

                log.info("🔍 家乡多值查询: 原始值={}, 拆分后={}", facebookUserEs.getBirthPlace(), String.join(",", birthPlaces));

                for (String birthPlace : birthPlaces) {
                    String trimmedBirthPlace = birthPlace.trim();
                    if (!trimmedBirthPlace.isEmpty()) {
                        MatchQueryBuilder birthPlaceQuery =
                                QueryBuilders.matchQuery(EsFacebookFields.BIRTH_PLACE, trimmedBirthPlace);
                        birthPlaceBool.should(birthPlaceQuery);
                        log.debug("🔍 添加家乡查询条件: {}", trimmedBirthPlace);
                    }
                }

                bq.must(birthPlaceBool); // 修复：添加到主查询中
            } else {
                // 单值查询
                MatchQueryBuilder birthPlaceQueryBuilder =
                        QueryBuilders.matchQuery(EsFacebookFields.BIRTH_PLACE, facebookUserEs.getBirthPlace());
                bq.must(birthPlaceQueryBuilder);
                log.info("🔍 家乡单值查询: {}", facebookUserEs.getBirthPlace());
            }
        }

        // 当前所在地多值查询支持
        if (facebookUserEs.getWorkplaceCity() != null && !facebookUserEs.getWorkplaceCity().isEmpty()) {
            BoolQueryBuilder workplaceCityBool = QueryBuilders.boolQuery();

            if (facebookUserEs.getWorkplaceCity().contains("、")) {
                // 多值查询：使用OR逻辑
                String[] workplaceCities = facebookUserEs.getWorkplaceCity().split("、");
                workplaceCityBool.minimumShouldMatch(1);

                log.info("🔍 当前所在地多值查询: 原始值={}, 拆分后={}", facebookUserEs.getWorkplaceCity(), String.join(",", workplaceCities));

                for (String workplaceCity : workplaceCities) {
                    String trimmedWorkplaceCity = workplaceCity.trim();
                    if (!trimmedWorkplaceCity.isEmpty()) {
                        MatchQueryBuilder workplaceCityQuery =
                                QueryBuilders.matchQuery(EsFacebookFields.WORKPLACE_CITY, trimmedWorkplaceCity);
                        workplaceCityBool.should(workplaceCityQuery);
                        log.debug("🔍 添加当前所在地查询条件: {}", trimmedWorkplaceCity);
                    }
                }

                bq.must(workplaceCityBool);
            } else {
                // 单值查询
                MatchQueryBuilder workplaceCityQueryBuilder =
                        QueryBuilders.matchQuery(EsFacebookFields.WORKPLACE_CITY, facebookUserEs.getWorkplaceCity());
                bq.must(workplaceCityQueryBuilder);
                log.info("🔍 当前所在地单值查询: {}", facebookUserEs.getWorkplaceCity());
            }
        }

        // 关系状态多值查询支持
        if (facebookUserEs.getMaritalStatus() != null && !facebookUserEs.getMaritalStatus().isEmpty()) {
            BoolQueryBuilder maritalStatusBool = QueryBuilders.boolQuery();

            if (facebookUserEs.getMaritalStatus().contains("、")) {
                // 多值查询：使用OR逻辑
                String[] maritalStatuses = facebookUserEs.getMaritalStatus().split("、");
                maritalStatusBool.minimumShouldMatch(1);

                log.info("🔍 关系状态多值查询: 原始值={}, 拆分后={}", facebookUserEs.getMaritalStatus(), String.join(",", maritalStatuses));

                for (String maritalStatus : maritalStatuses) {
                    String trimmedMaritalStatus = maritalStatus.trim();
                    if (!trimmedMaritalStatus.isEmpty()) {
                        MatchQueryBuilder maritalStatusQuery =
                                QueryBuilders.matchQuery(EsFacebookFields.MARITAL_STATUS, trimmedMaritalStatus);
                        maritalStatusBool.should(maritalStatusQuery);
                        log.debug("🔍 添加关系状态查询条件: {}", trimmedMaritalStatus);
                    }
                }

                bq.must(maritalStatusBool);
            } else {
                // 单值查询
                MatchQueryBuilder maritalStatusQueryBuilder =
                        QueryBuilders.matchQuery(EsFacebookFields.MARITAL_STATUS, facebookUserEs.getMaritalStatus());
                bq.must(maritalStatusQueryBuilder);
                log.info("🔍 关系状态单值查询: {}", facebookUserEs.getMaritalStatus());
            }
        }

        if (facebookUserEs.getContactMethod() != null &&
                !facebookUserEs.getContactMethod().isEmpty() &&
                !facebookUserEs.getContactMethod().equals("any")) {

            String contactMethod = facebookUserEs.getContactMethod();
            log.debug("处理联系方式筛选: {}", contactMethod);

            if (contactMethod.equals("email")) {
                // 检查email字段存在且不为空，并且包含@符号
                BoolQueryBuilder emailQuery = QueryBuilders.boolQuery()
                        .must(QueryBuilders.existsQuery(EsFacebookFields.EMAIL))
                        .mustNot(QueryBuilders.termQuery(EsFacebookFields.EMAIL, ""))
                        .must(QueryBuilders.wildcardQuery(EsFacebookFields.EMAIL, "*@*"));
                bq.must(emailQuery);
                log.debug("添加email查询条件: 字段存在且不为空且包含@符号");
            } else if (contactMethod.equals("phone")) {
                // 检查phone_number字段存在且不为空
                BoolQueryBuilder phoneQuery = QueryBuilders.boolQuery()
                        .must(QueryBuilders.existsQuery(EsFacebookFields.PHONE_NUMBER))
                        .mustNot(QueryBuilders.termQuery(EsFacebookFields.PHONE_NUMBER, ""));
                bq.must(phoneQuery);
                log.debug("添加phone查询条件: 字段存在且不为空");
            }
        }

        // 分页参数验证和处理
        long currentPage = Math.max(facebookUserEs.getCurrent(), 1);  // 页码至少为1
        long pageSize = facebookUserEs.getSize() > 0 ? facebookUserEs.getSize() : 10;  // 默认每页10条

        // 限制分页大小，防止过大的查询
        if (pageSize > 1000) {
            log.warn("分页大小过大，调整为最大值: {} -> 1000", pageSize);
            pageSize = 1000;
        }

        long from = (currentPage - 1) * pageSize;

        log.debug("分页参数: currentPage={}, pageSize={}, from={}", currentPage, pageSize, from);

        esSearchRequest.setBq(bq);
        esSearchRequest.setFields(EsFacebookFields.FIELD_QUERY);
        esSearchRequest.setFrom(from);
        esSearchRequest.setSize(pageSize);  // 修复：使用计算后的 pageSize，确保值有效
        esSearchRequest.setNeedScroll(false);

        // 添加一致的排序规则，确保分页查询和导出查询结果顺序一致
        // 按照 mysql_id 降序排序，实现最新数据在前（假设 mysql_id 是自增的）
        esSearchRequest.setSortName(EsFacebookFields.SORT_FIELD_PRIMARY);
        esSearchRequest.setSortOrder(EsFacebookFields.SORT_ORDER_NEWEST_FIRST);

        log.debug("最终ES查询条件: {}, from={}, size={}, sort={}:{}", bq.toString(), from, pageSize,
                EsFacebookFields.SORT_FIELD_PRIMARY, EsFacebookFields.SORT_ORDER_NEWEST_FIRST);
        return esSearchRequest;
    }

    // ==================== 两阶段查询实现 ====================

    @Override
    public List<Map<String, String>> searchByNameAndWorkplace(String firstName, String lastName, String workplace, int limit) {
        log.info("ES两阶段查询 - 姓名+工作地点: firstName={}, lastName={}, workplace={}, limit={}",
                firstName, lastName, workplace, limit);

        try {
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

            // 姓名匹配（必须条件）
            if (firstName != null && !firstName.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.FIRST_NAME, firstName));
            }
            if (lastName != null && !lastName.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.LAST_NAME, lastName));
            }

            // 工作地点匹配（必须条件）- 支持多值查询
            if (workplace != null && !workplace.trim().isEmpty()) {
                BoolQueryBuilder workplaceQuery = buildMultiValueQuery(
                        workplace.trim(),
                        EsFacebookFields.WORK_PLACE,
                        "工作地点"
                );
                boolQuery.must(workplaceQuery);
            }

            return executeEsSearchForIdentifiers(boolQuery, Math.min(limit, 50), 0);

        } catch (Exception e) {
            log.error("ES查询失败 - 姓名+工作地点: firstName={}, lastName={}, workplace={}, error={}",
                    firstName, lastName, workplace, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Map<String, String>> searchByNameAndEmail(String firstName, String lastName, String email, int limit) {
        log.info("ES两阶段查询 - 姓名+邮箱: firstName={}, lastName={}, email={}, limit={}",
                firstName, lastName, email, limit);

        try {
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

            // 姓名匹配（必须条件）
            if (firstName != null && !firstName.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.FIRST_NAME, firstName));
            }
            if (lastName != null && !lastName.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.LAST_NAME, lastName));
            }

            // 邮箱匹配（必须条件）
            if (email != null && !email.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.termQuery(EsFacebookFields.EMAIL, email.toLowerCase()));
            }

            return executeEsSearchForIdentifiers(boolQuery, Math.min(limit, 50), 0);

        } catch (Exception e) {
            log.error("ES查询失败 - 姓名+邮箱: firstName={}, lastName={}, email={}, error={}",
                    firstName, lastName, email, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Map<String, String>> searchByPhoneAndName(String phoneNumber, String firstName, String lastName, int limit) {
        log.info("ES两阶段查询 - 手机号+姓名: phoneNumber={}, firstName={}, lastName={}, limit={}",
                phoneNumber, firstName, lastName, limit);

        try {
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

            // 手机号匹配（必须条件）
            if (phoneNumber != null && !phoneNumber.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.termQuery(EsFacebookFields.PHONE_NUMBER, phoneNumber));
            }

            // 姓名匹配（必须条件）
            if (firstName != null && !firstName.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.FIRST_NAME, firstName));
            }
            if (lastName != null && !lastName.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.LAST_NAME, lastName));
            }

            return executeEsSearchForIdentifiers(boolQuery, Math.min(limit, 50), 0);

        } catch (Exception e) {
            log.error("ES查询失败 - 手机号+姓名: phoneNumber={}, firstName={}, lastName={}, error={}",
                    phoneNumber, firstName, lastName, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Map<String, String>> searchByEmail(String email, int limit, int offset) {
        log.info("ES两阶段查询 - 邮箱精确匹配: email={}, limit={}, offset={}", email, limit, offset);

        try {
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

            // 邮箱精确匹配（必须条件）
            if (email != null && !email.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.termQuery(EsFacebookFields.EMAIL, email.toLowerCase()));
            }

            return executeEsSearchForIdentifiers(boolQuery, Math.min(limit, 50), offset);

        } catch (Exception e) {
            log.error("ES查询失败 - 邮箱精确匹配: email={}, error={}", email, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Map<String, String>> searchByPhone(String phone, int limit, int offset) {
        log.info("ES两阶段查询 - 手机号精确匹配: phone={}, limit={}, offset={}", phone, limit, offset);

        try {
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

            // 手机号精确匹配（必须条件）
            if (phone != null && !phone.trim().isEmpty()) {
                boolQuery.must(QueryBuilders.termQuery(EsFacebookFields.PHONE_NUMBER, phone));
            }

            return executeEsSearchForIdentifiers(boolQuery, Math.min(limit, 50), offset);

        } catch (Exception e) {
            log.error("ES查询失败 - 手机号精确匹配: phone={}, error={}", phone, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 执行ES查询并返回标识信息
     *
     * @param boolQuery 布尔查询条件
     * @param limit     最大返回数量
     * @return 包含mysqlTable和id的结果列表
     */
    private List<Map<String, String>> executeEsSearchForIdentifiers(BoolQueryBuilder boolQuery, int limit, int offset) {
        List<Map<String, String>> results = new ArrayList<>();

        try {
            // 创建ES搜索请求
            EsSearchRequest esSearchRequest = new EsSearchRequest();
            esSearchRequest.setBq(boolQuery);
            esSearchRequest.setFrom((long) offset);
            esSearchRequest.setSize((long) limit);
            esSearchRequest.setNeedScroll(false);

            // 添加排序规则，确保与分页查询一致
            esSearchRequest.setSortName(EsFacebookFields.SORT_FIELD_PRIMARY);
            esSearchRequest.setSortOrder(EsFacebookFields.SORT_ORDER_NEWEST_FIRST);

            // 只查询必要的字段以提升性能
            String[] fields = {EsFacebookFields.MYSQL_TABLE, EsFacebookFields.MYSQL_ID};
            esSearchRequest.setFields(fields);

            log.debug("执行ES查询，条件: {}, limit: {}, sort: {}:{}", boolQuery.toString(), limit,
                    EsFacebookFields.SORT_FIELD_PRIMARY, EsFacebookFields.SORT_ORDER_NEWEST_FIRST);

            // 执行查询
            SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

            if (searchResponse == null) {
                log.warn("ES查询返回null响应");
                return results;
            }

            SearchHits searchHits = searchResponse.getHits();
            if (searchHits == null || searchHits.getHits() == null) {
                log.warn("ES查询返回空结果");
                return results;
            }

            SearchHit[] hits = searchHits.getHits();
            log.info("ES查询返回{}条匹配记录", hits.length);

            // 提取标识信息
            for (SearchHit hit : hits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                if (sourceAsMap != null) {
                    Map<String, String> identifier = new HashMap<>();
                    identifier.put("mysqlTable", getStringSafely(sourceAsMap, EsFacebookFields.MYSQL_TABLE));
                    identifier.put("id", getStringSafely(sourceAsMap, EsFacebookFields.MYSQL_ID));

                    // 验证标识信息完整性
                    if (identifier.get("mysqlTable") != null && identifier.get("id") != null) {
                        results.add(identifier);
                        log.debug("添加匹配记录: mysqlTable={}, id={}",
                                identifier.get("mysqlTable"), identifier.get("id"));
                    } else {
                        log.warn("跳过不完整的记录: mysqlTable={}, id={}",
                                identifier.get("mysqlTable"), identifier.get("id"));
                    }
                }
            }

            log.info("ES查询完成，有效匹配记录数: {}", results.size());
            return results;

        } catch (Exception e) {
            log.error("执行ES查询失败: {}", e.getMessage(), e);
            return results;
        }
    }

    // ==================== 导出功能两阶段查询实现 ====================

    @Override
    public List<Map<String, String>> searchForExport(FacebookQueryDTO queryDTO, int limit) {
        log.info("ES两阶段查询 - 导出数据: queryDTO={}, limit={}", queryDTO, limit);

        try {
            // 如果请求的数据量小于等于10000，直接使用单次查询
            if (limit <= 10000) {
            BoolQueryBuilder boolQuery = buildExportQuery(queryDTO);
                return executeEsSearchForIdentifiers(boolQuery, limit, 0);
            } else {
                // 超过10000条时，使用分批查询
                return searchForExportWithBatching(queryDTO, limit);
            }
        } catch (Exception e) {
            log.error("ES导出查询失败: queryDTO={}, error={}", queryDTO, e.getMessage(), e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 分批查询导出数据，解决Elasticsearch默认max_result_window=10000的限制
     *
     * @param queryDTO 查询条件
     * @param limit 查询限制
     * @return 查询结果
     */
    private List<Map<String, String>> searchForExportWithBatching(FacebookQueryDTO queryDTO, int limit) {
        log.info("ES分批查询 - 使用Scroll API导出数据: queryDTO={}, limit={}", queryDTO, limit);
        
        List<Map<String, String>> allResults = new ArrayList<>();
        BoolQueryBuilder boolQuery = buildExportQuery(queryDTO);
        
        try {
            // 创建ES搜索请求
            EsSearchRequest esSearchRequest = new EsSearchRequest();
            esSearchRequest.setBq(boolQuery);
            esSearchRequest.setFrom(0L);
            esSearchRequest.setSize(5000L);  // 每批5000条
            esSearchRequest.setNeedScroll(true);  // 启用scroll
            esSearchRequest.setScrollTime("5m");  // scroll保持5分钟有效
            
            // 只查询必要的字段以提升性能
            String[] fields = {EsFacebookFields.MYSQL_TABLE, EsFacebookFields.MYSQL_ID};
            esSearchRequest.setFields(fields);
            
            // 添加排序规则，确保结果一致性
            esSearchRequest.setSortName(EsFacebookFields.SORT_FIELD_PRIMARY);
            esSearchRequest.setSortOrder(EsFacebookFields.SORT_ORDER_NEWEST_FIRST);
            
            log.info("开始执行ES Scroll查询，初始大小: {}", esSearchRequest.getSize());
            
            // 执行初始查询，获取scrollId
            SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);
            if (searchResponse == null) {
                log.warn("ES Scroll查询返回null响应");
                return allResults;
            }
            
            String scrollId = searchResponse.getScrollId();
            if (scrollId == null) {
                log.warn("ES Scroll查询未返回scrollId");
                return allResults;
            }
            
            int batchCount = 0;
            int totalFetched = 0;
            
            // 处理初始批次
            totalFetched += processScrollResponse(searchResponse, allResults);
            batchCount++;
            log.info("批次 #{}: 获取{}条记录，累计{}条", batchCount, 
                    totalFetched, allResults.size());
            
            // 继续使用scrollId获取后续批次
            while (scrollId != null && totalFetched < limit) {
                // 确保不超过请求的数量限制
                if (allResults.size() >= limit) {
                    log.info("已达到请求的数量限制: {}, 停止查询", limit);
                    break;
                }
                
                try {
                    // 使用scrollId获取下一批结果
                    searchResponse = EsRestClient.searchScroll(scrollId, "5m");
                    if (searchResponse == null) {
                        log.warn("ES Scroll继续查询返回null响应");
                        break;
                    }
                    
                    // 更新scrollId
                    scrollId = searchResponse.getScrollId();
                    
                    SearchHits hits = searchResponse.getHits();
                    if (hits == null || hits.getHits() == null || hits.getHits().length == 0) {
                        log.info("没有更多结果，终止Scroll查询");
                        break;
                    }
                    
                    // 处理当前批次
                    int currentBatchSize = processScrollResponse(searchResponse, allResults);
                    totalFetched += currentBatchSize;
                    batchCount++;
                    
                    log.info("批次 #{}: 获取{}条记录，累计{}条", batchCount, 
                            currentBatchSize, allResults.size());
                    
                    // 如果当前批次返回的数据量小于请求的大小，说明已经没有更多数据了
                    if (currentBatchSize == 0) {
                        log.info("当前批次返回0条记录，终止查询");
                        break;
                    }
                    
                    // 避免快速连续请求导致ES过载
                    Thread.sleep(200);
                    
                } catch (Exception e) {
                    log.error("ES Scroll继续查询失败: {}", e.getMessage(), e);
                    break;
                }
            }
            
            // 清理scroll上下文，释放资源
            try {
                if (scrollId != null) {
                    EsRestClient.clearScroll(scrollId);
                    log.info("成功清理ES Scroll上下文");
                }
            } catch (Exception e) {
                log.warn("清理ES Scroll上下文失败: {}", e.getMessage());
            }
            
        } catch (Exception e) {
            log.error("执行ES Scroll查询失败: {}", e.getMessage(), e);
        }
        
        // 如果结果超过了请求的限制，截断结果
        if (allResults.size() > limit) {
            log.info("结果数量{}超过请求限制{}，进行截断", allResults.size(), limit);
            allResults = allResults.subList(0, limit);
        }
        
        log.info("ES Scroll查询完成，总共获取{}条结果", allResults.size());
        return allResults;
    }
    
    /**
     * 处理scroll查询响应，提取标识信息
     *
     * @param searchResponse ES搜索响应
     * @param results 结果集合
     * @return 当前批次处理的记录数
     */
    private int processScrollResponse(SearchResponse searchResponse, List<Map<String, String>> results) {
        if (searchResponse == null) {
            return 0;
        }
        
        SearchHits searchHits = searchResponse.getHits();
        if (searchHits == null || searchHits.getHits() == null) {
            return 0;
        }
        
        SearchHit[] hits = searchHits.getHits();
        int processedCount = 0;
        
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            if (sourceAsMap != null) {
                Map<String, String> identifier = new HashMap<>();
                identifier.put("mysqlTable", getStringSafely(sourceAsMap, EsFacebookFields.MYSQL_TABLE));
                identifier.put("id", getStringSafely(sourceAsMap, EsFacebookFields.MYSQL_ID));
                
                // 验证标识信息完整性
                if (identifier.get("mysqlTable") != null && identifier.get("id") != null) {
                    results.add(identifier);
                    processedCount++;
                }
            }
        }
        
        return processedCount;
    }

    @Override
    public List<Map<String, String>> searchForExportWithPagination(FacebookQueryDTO queryDTO, int from, int size) {
        log.info("ES两阶段查询 - 分页导出数据: queryDTO={}, from={}, size={}", queryDTO, from, size);

        try {
            BoolQueryBuilder boolQuery = buildExportQuery(queryDTO);
            return executeEsSearchForIdentifiersWithPagination(boolQuery, from, size);

        } catch (Exception e) {
            log.error("ES分页导出查询失败: queryDTO={}, from={}, size={}, error={}", queryDTO, from, size, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    public long countForExport(FacebookQueryDTO queryDTO) {
        log.info("ES查询计数 - 导出数据: queryDTO={}", queryDTO);

        try {
            BoolQueryBuilder boolQuery = buildExportQuery(queryDTO);
            return executeEsCountQuery(boolQuery);

        } catch (Exception e) {
            log.error("ES计数查询失败: queryDTO={}, error={}", queryDTO, e.getMessage(), e);
            return 0;
        }
    }

    @Override
    public List<FacebookUserEs> searchFacebookUsersWithEmail(String searchKeyword, int offset, int size) {

        log.info("FacebookES查询Email数据，参数： searchKeyWord={}，offset={}，size={}", searchKeyword, offset, size);

        FacebookUserEs facebookUserEs = new FacebookUserEs();

        facebookUserEs.setFirstName(searchKeyword);
        facebookUserEs.setLastName(searchKeyword);
        facebookUserEs.setFullName(searchKeyword);
        facebookUserEs.setWorkPlace(searchKeyword);
        facebookUserEs.setContactMethod("email");
        facebookUserEs.setPages(offset);
        facebookUserEs.setSize(size);

        EsSearchRequest esSearchRequest = createEsSearchWithEmailAndPhoneRequest(facebookUserEs);
        SearchResponse searchResponse =
                EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

        List<FacebookUserEs> facebookUserEsList = new LinkedList<>();
        SearchHits searchHits = null;
        if (searchResponse != null) {
            searchHits = searchResponse.getHits();
        }
        if (searchHits == null || searchHits.getHits() == null) {
            return facebookUserEsList;
        }

        SearchHit[] hits = searchHits.getHits();

        for (SearchHit hit : hits) {
            facebookUserEs = convertResult(hit);
            if (Objects.nonNull(facebookUserEs)) {
                facebookUserEsList.add(facebookUserEs);
            } else {
                log.warn("🔍 ES查询调试 - 数据转换失败: hitId={}", hit.getId());
            }
        }
        return facebookUserEsList;
    }

    @Override
    public Long countFacebookUsersWithEmail(String searchKeyword) {
        log.info("FacebookES查询Email数据量，参数： searchKeyWord={}", searchKeyword);

        FacebookUserEs facebookUserEs = new FacebookUserEs();

        facebookUserEs.setFirstName(searchKeyword);
        facebookUserEs.setLastName(searchKeyword);
        facebookUserEs.setFullName(searchKeyword);
        facebookUserEs.setWorkPlace(searchKeyword);
        facebookUserEs.setContactMethod("email");

        EsSearchRequest esSearchRequest = createEsCountWithEmailAndPhoneRequest(facebookUserEs);
        SearchResponse searchResponse =
                EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

        if (searchResponse == null) {
            log.warn("ES计数查询返回null响应");
            return 0L;
        }

        SearchHits searchHits = searchResponse.getHits();
        if (searchHits == null) {
            log.warn("ES计数查询返回空结果");
            return 0L;
        }

        long totalCount = 0;
        if (searchHits.getTotalHits() != null) {
            totalCount = searchHits.getTotalHits().value;
        }
        log.info("ES计数查询完成，匹配记录总数: {}", totalCount);

        return totalCount;

    }

    @Override
    public List<FacebookUserEs> searchFacebookUsersWithPhone(String searchKeyword, int offset, int size) {
        log.info("FacebookES查询Phone数据，参数： searchKeyWord={}，offset={}，size={}", searchKeyword, offset, size);

        FacebookUserEs facebookUserEs = new FacebookUserEs();

        facebookUserEs.setFirstName(searchKeyword);
        facebookUserEs.setLastName(searchKeyword);
        facebookUserEs.setFullName(searchKeyword);
        facebookUserEs.setWorkPlace(searchKeyword);
        facebookUserEs.setContactMethod("phone");
        facebookUserEs.setPages(offset);
        facebookUserEs.setSize(size);

        EsSearchRequest esSearchRequest = createEsSearchWithEmailAndPhoneRequest(facebookUserEs);
        SearchResponse searchResponse =
                EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

        List<FacebookUserEs> facebookUserEsList = new LinkedList<>();
        SearchHits searchHits = null;
        if (searchResponse != null) {
            searchHits = searchResponse.getHits();
        }
        if (searchHits == null || searchHits.getHits() == null) {
            return facebookUserEsList;
        }

        SearchHit[] hits = searchHits.getHits();

        for (SearchHit hit : hits) {
            facebookUserEs = convertResult(hit);
            if (Objects.nonNull(facebookUserEs)) {
                facebookUserEsList.add(facebookUserEs);
            } else {
                log.warn("🔍 ES查询调试 - 数据转换失败: hitId={}", hit.getId());
            }
        }
        return facebookUserEsList;
    }

    @Override
    public Long countFacebookUsersWithPhone(String searchKeyword) {
        log.info("FacebookES查询Phone数据量，参数： searchKeyWord={}", searchKeyword);

        FacebookUserEs facebookUserEs = new FacebookUserEs();

        facebookUserEs.setFirstName(searchKeyword);
        facebookUserEs.setLastName(searchKeyword);
        facebookUserEs.setFullName(searchKeyword);
        facebookUserEs.setWorkPlace(searchKeyword);
        facebookUserEs.setContactMethod("phone");

        EsSearchRequest esSearchRequest = createEsCountWithEmailAndPhoneRequest(facebookUserEs);
        SearchResponse searchResponse =
                EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

        if (searchResponse == null) {
            log.warn("ES计数查询返回null响应");
            return 0L;
        }

        SearchHits searchHits = searchResponse.getHits();
        if (searchHits == null) {
            log.warn("ES计数查询返回空结果");
            return 0L;
        }

        long totalCount = 0;
        if (searchHits.getTotalHits() != null) {
            totalCount = searchHits.getTotalHits().value;
        }
        log.info("ES计数查询完成，匹配记录总数: {}", totalCount);

        return totalCount;
    }

    @Override
    public long countByEmail(String email) {
        log.info("FacebookES查询email数据量，参数： email={}", email);

        FacebookQueryDTO facebookQueryDTO = new FacebookQueryDTO();

        facebookQueryDTO.setEmail(email);

        return countForExport(facebookQueryDTO);
    }

    @Override
    public long countByPhone(String phone) {
        log.info("FacebookES查询phone数据量，参数： phone={}", phone);

        FacebookQueryDTO facebookQueryDTO = new FacebookQueryDTO();

        facebookQueryDTO.setPhoneNumber(phone);

        return countForExport(facebookQueryDTO);
    }

    @Override
    public List<String> searchCurrent(String current) {
        // 使用Set自动去重
        Set<String> uniqueCities = new HashSet<>();

        BoolQueryBuilder bq = new BoolQueryBuilder();
        bq.should(QueryBuilders.wildcardQuery(EsFacebookFields.WORKPLACE_CITY,   current + "*"));
        bq.should(QueryBuilders.matchQuery(EsFacebookFields.WORKPLACE_CITY, current).fuzziness("AUTO"));
// 执行搜索并获取城市列表
        List<Map<String, Object>> results = executeEsSearchForCurrent(bq, current);
// 提取并去重城市名称
        for (Map<String, Object> result : results) {
            Object cityObj = result.get(EsFacebookFields.WORKPLACE_CITY);
            if (cityObj != null) {
                if (cityObj instanceof String) {
                    uniqueCities.add((String) cityObj);
                } else if (cityObj instanceof List) {
                    for (Object item : (List<?>) cityObj) {
                        if (item instanceof String) {
                            uniqueCities.add((String) item);
                        }
                    }
                }
            }
        }

        // 转换为列表并返回
        return new ArrayList<>(uniqueCities);
    }

    @Override
    public List<String> searchHometown(String hometowm) {
        // 使用Set自动去重
        Set<String> uniqueCities = new HashSet<>();

        BoolQueryBuilder bq = new BoolQueryBuilder();
        bq.should(QueryBuilders.wildcardQuery(EsFacebookFields.BIRTH_PLACE,   hometowm + "*"));
        bq.should(QueryBuilders.matchQuery(EsFacebookFields.BIRTH_PLACE, hometowm).fuzziness("AUTO"));
// 执行搜索并获取城市列表
        List<Map<String, Object>> results = executeEsSearchForHometown(bq, hometowm);
// 提取并去重城市名称
        for (Map<String, Object> result : results) {
            Object cityObj = result.get(EsFacebookFields.BIRTH_PLACE);
            if (cityObj != null) {
                if (cityObj instanceof String) {
                    uniqueCities.add((String) cityObj);
                } else if (cityObj instanceof List) {
                    for (Object item : (List<?>) cityObj) {
                        if (item instanceof String) {
                            uniqueCities.add((String) item);
                        }
                    }
                }
            }
        }

        // 转换为列表并返回
        return new ArrayList<>(uniqueCities);
    }

    @Override
    public List<String> searchWorkplaces(String workplace) {
        // 使用Set自动去重
        Set<String> uniqueCities = new HashSet<>();

        BoolQueryBuilder bq = new BoolQueryBuilder();
        bq.should(QueryBuilders.wildcardQuery(EsFacebookFields.WORK_PLACE,   workplace + "*"));
        bq.should(QueryBuilders.matchQuery(EsFacebookFields.WORK_PLACE, workplace).fuzziness("AUTO"));
// 执行搜索并获取城市列表
        List<Map<String, Object>> results = executeEsSearchForWorkplaces(bq, workplace);
// 提取并去重城市名称
        for (Map<String, Object> result : results) {
            Object cityObj = result.get(EsFacebookFields.WORK_PLACE);
            if (cityObj != null) {
                if (cityObj instanceof String) {
                    uniqueCities.add((String) cityObj);
                } else if (cityObj instanceof List) {
                    for (Object item : (List<?>) cityObj) {
                        if (item instanceof String) {
                            uniqueCities.add((String) item);
                        }
                    }
                }
            }
        }

        // 转换为列表并返回
        return new ArrayList<>(uniqueCities);
    }

    @Override
    public List<FacebookUserEs> searchFacebookDataWithPhone(String companyName, String fullName) {
        log.info("FacebookES查询Phone数据量，参数： companyName={}, fullName={}", companyName, fullName);

        FacebookUserEs facebookUserEs = new FacebookUserEs();
        facebookUserEs.setWorkPlace(companyName);
//        facebookUserEs.setLastName(fullName);
        facebookUserEs.setFullName(fullName);
        facebookUserEs.setContactMethod("phone");

        EsSearchRequest esSearchRequest = createEsBatchSearchWithEmailAndPhoneRequest(facebookUserEs);

        // 使用scroll查询获取所有数据
        SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

        List<FacebookUserEs> facebookUserEsList = new LinkedList<>();

        if (searchResponse != null && searchResponse.getHits() != null) {
            SearchHits hits = searchResponse.getHits();
            if (hits.getTotalHits() != null) {
                log.info("Facebook ES查询完成，共找到{}条匹配数据", hits.getTotalHits().value);
            }

            for (SearchHit hit : hits.getHits()) {
                FacebookUserEs user = convertResultFromMap(hit.getSourceAsMap());
                if (user != null) {
                    facebookUserEsList.add(user);
                }
            }
        }

        return facebookUserEsList;
    }

    private EsSearchRequest createEsBatchSearchWithEmailAndPhoneRequest(FacebookUserEs facebookUserEs) {

        log.debug("创建FacebookES查询请求: phoneNumber={}, workPlace={}, workplaceCity={}, birthPlace={},  contactMethod={}, fullName={}, firstName={}, lastName={}",
                facebookUserEs.getPhoneNumber(), facebookUserEs.getWorkPlace(),
                facebookUserEs.getWorkplaceCity(), facebookUserEs.getBirthPlace(),
                facebookUserEs.getContactMethod(), facebookUserEs.getFullName(),
                facebookUserEs.getFirstName(), facebookUserEs.getLastName());

        EsSearchRequest esSearchRequest = new EsSearchRequest();
        BoolQueryBuilder bq = new BoolQueryBuilder();

        searchBatchEs(facebookUserEs, bq);
        esSearchRequest.setBq(bq);
        esSearchRequest.setFields(EsFacebookFields.FIELD_QUERY);

        // 使用普通分页查询，限制最多返回5000条，避免查询过多数据
        esSearchRequest.setNeedScroll(false); // 不使用Scroll，使用普通查询
        esSearchRequest.setFrom(0L); // 设置起始位置
        esSearchRequest.setSize(5000L); // 最多返回5000条记录

        log.info("执行Facebook ES查询，限制最多返回5000条结果");

        return esSearchRequest;

    }

    private void searchBatchEs(FacebookUserEs facebookUserEs, BoolQueryBuilder bq) {

        if (facebookUserEs.getWorkPlace() != null && !facebookUserEs.getWorkPlace().isEmpty()) {
            bq.must(QueryBuilders.matchQuery(EsFacebookFields.WORK_PLACE + ".keyword", facebookUserEs.getWorkPlace()));
        }

        // 姓名相关查询条件
        if (facebookUserEs.getFullName() != null && !facebookUserEs.getFullName().isEmpty()) {
            // 全名查询给予更高权重
            bq.must(QueryBuilders.matchQuery(EsFacebookFields.FULL_NAME + ".keyword", facebookUserEs.getFullName()));
        }

        // 联系方式查询保持为must条件（必须满足）
        if (facebookUserEs.getContactMethod() != null && !facebookUserEs.getContactMethod().isEmpty()) {
            String contactMethod = facebookUserEs.getContactMethod();
            if (contactMethod.equals("email")) {
                BoolQueryBuilder emailQuery = QueryBuilders.boolQuery()
                        .must(QueryBuilders.existsQuery(EsFacebookFields.EMAIL))
                        .mustNot(QueryBuilders.termQuery(EsFacebookFields.EMAIL, ""));
                bq.must(emailQuery);
            } else if (contactMethod.equals("phone")) {
                BoolQueryBuilder phoneQuery = QueryBuilders.boolQuery()
                        .must(QueryBuilders.existsQuery(EsFacebookFields.PHONE_NUMBER))
                        .mustNot(QueryBuilders.termQuery(EsFacebookFields.PHONE_NUMBER, ""));
                bq.must(phoneQuery);
            }
        }

    }

    @Override
    public List<FacebookUserEs> searchFacebookDataWithEmail(String companyName, String fullName) {

        FacebookUserEs facebookUserEs = new FacebookUserEs();
        facebookUserEs.setWorkPlace(companyName);
        facebookUserEs.setFullName(fullName);
        facebookUserEs.setContactMethod("email");

        EsSearchRequest esSearchRequest = createEsBatchSearchWithEmailAndPhoneRequest(facebookUserEs);

        // 使用普通查询而非scroll查询
        SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

        List<FacebookUserEs> facebookUserEsList = new LinkedList<>();

        if (searchResponse != null && searchResponse.getHits() != null) {
            SearchHits hits = searchResponse.getHits();
            if (hits.getTotalHits() != null) {
                log.info("Facebook ES查询完成，共找到{}条匹配数据", hits.getTotalHits().value);
            }

            for (SearchHit hit : hits.getHits()) {
                FacebookUserEs user = convertResultFromMap(hit.getSourceAsMap());
                if (user != null) {
                    facebookUserEsList.add(user);
                }
            }
        }

        return facebookUserEsList;

    }

    private List<Map<String, Object>> executeEsSearchForWorkplaces(BoolQueryBuilder boolQuery, String workplace) {
        List<Map<String, Object>> results = new ArrayList<>();
        final int MAX_RESULTS = 20; // 限制最大结果数

        try {
            // 创建ES搜索请求
            EsSearchRequest esSearchRequest = new EsSearchRequest();
            esSearchRequest.setBq(boolQuery);
            esSearchRequest.setFrom(0L);
            esSearchRequest.setSize((long) MAX_RESULTS);
            esSearchRequest.setNeedScroll(false);

            // 只查询当前所在地字段
            String[] fields = {EsFacebookFields.WORK_PLACE};
            esSearchRequest.setFields(fields);

            // 执行查询
            SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

            if (searchResponse == null) {
                log.warn("ES查询返回null响应");
                return results;
            }

            SearchHits searchHits = searchResponse.getHits();
            if (searchHits == null || searchHits.getHits() == null) {
                log.warn("ES查询返回空结果");
                return results;
            }

            SearchHit[] hits = searchHits.getHits();
            log.info("ES查询返回{}条匹配记录", hits.length);

            // 提取城市信息
            for (SearchHit hit : hits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                if (sourceAsMap != null && sourceAsMap.containsKey(EsFacebookFields.WORK_PLACE)) {
                    results.add(sourceAsMap);
                }
            }

            log.info("ES查询完成，有效匹配记录数: {}", results.size());
            return results;

        } catch (Exception e) {
            log.error("执行ES查询失败: {}", e.getMessage(), e);
            return results;
        }
    }

    private List<Map<String, Object>> executeEsSearchForHometown(BoolQueryBuilder boolQuery, String hometowm) {
        List<Map<String, Object>> results = new ArrayList<>();
        final int MAX_RESULTS = 20; // 限制最大结果数

        try {
            // 创建ES搜索请求
            EsSearchRequest esSearchRequest = new EsSearchRequest();
            esSearchRequest.setBq(boolQuery);
            esSearchRequest.setFrom(0L);
            esSearchRequest.setSize((long) MAX_RESULTS);
            esSearchRequest.setNeedScroll(false);

            // 只查询当前所在地字段
            String[] fields = {EsFacebookFields.BIRTH_PLACE};
            esSearchRequest.setFields(fields);

            // 执行查询
            SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

            if (searchResponse == null) {
                log.warn("ES查询返回null响应");
                return results;
            }

            SearchHits searchHits = searchResponse.getHits();
            if (searchHits == null || searchHits.getHits() == null) {
                log.warn("ES查询返回空结果");
                return results;
            }

            SearchHit[] hits = searchHits.getHits();
            log.info("ES查询返回{}条匹配记录", hits.length);

            // 提取城市信息
            for (SearchHit hit : hits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                if (sourceAsMap != null && sourceAsMap.containsKey(EsFacebookFields.BIRTH_PLACE)) {
                    results.add(sourceAsMap);
                }
            }

            log.info("ES查询完成，有效匹配记录数: {}", results.size());
            return results;

        } catch (Exception e) {
            log.error("执行ES查询失败: {}", e.getMessage(), e);
            return results;
        }
    }

    private List<Map<String, Object>> executeEsSearchForCurrent(BoolQueryBuilder boolQuery, String current) {
        List<Map<String, Object>> results = new ArrayList<>();
        final int MAX_RESULTS = 20; // 限制最大结果数

        try {
            // 创建ES搜索请求
            EsSearchRequest esSearchRequest = new EsSearchRequest();
            esSearchRequest.setBq(boolQuery);
            esSearchRequest.setFrom(0L);
            esSearchRequest.setSize((long) MAX_RESULTS);
            esSearchRequest.setNeedScroll(false);

            // 只查询当前所在地字段
            String[] fields = {EsFacebookFields.WORKPLACE_CITY};
            esSearchRequest.setFields(fields);

            // 执行查询
            SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

            if (searchResponse == null) {
                log.warn("ES查询返回null响应");
                return results;
            }

            SearchHits searchHits = searchResponse.getHits();
            if (searchHits == null || searchHits.getHits() == null) {
                log.warn("ES查询返回空结果");
                return results;
            }

            SearchHit[] hits = searchHits.getHits();
            log.info("ES查询返回{}条匹配记录", hits.length);

            // 提取城市信息
            for (SearchHit hit : hits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                if (sourceAsMap != null && sourceAsMap.containsKey(EsFacebookFields.WORKPLACE_CITY)) {
                    results.add(sourceAsMap);
                }
            }

            log.info("ES查询完成，有效匹配记录数: {}", results.size());
            return results;

        } catch (Exception e) {
            log.error("执行ES查询失败: {}", e.getMessage(), e);
            return results;
        }
    }

    private EsSearchRequest createEsCountWithEmailAndPhoneRequest(FacebookUserEs facebookUserEs) {
        log.debug("创建FacebookES查询数量请求: phoneNumber={}, workPlace={}, workplaceCity={}, birthPlace={},  contactMethod={}, fullName={}, firstName={}, lastName={}",
                facebookUserEs.getPhoneNumber(), facebookUserEs.getWorkPlace(),
                facebookUserEs.getWorkplaceCity(), facebookUserEs.getBirthPlace(),
                facebookUserEs.getContactMethod(), facebookUserEs.getFullName(),
                facebookUserEs.getFirstName(), facebookUserEs.getLastName());

        // 创建ES搜索请求（只查询计数）
        EsSearchRequest esSearchRequest = new EsSearchRequest();


        BoolQueryBuilder bq = new BoolQueryBuilder();
        searchEs(facebookUserEs, bq);
        esSearchRequest.setBq(bq);
        esSearchRequest.setFrom(0L);
        esSearchRequest.setSize(0L); // 只查询计数，不返回具体记录
        esSearchRequest.setNeedScroll(false);
        esSearchRequest.setTrackTotalHits(true);

        return esSearchRequest;

    }

    private EsSearchRequest createEsSearchWithEmailAndPhoneRequest(FacebookUserEs facebookUserEs) {
        log.debug("创建FacebookES查询请求: phoneNumber={}, workPlace={}, workplaceCity={}, birthPlace={},  contactMethod={}, fullName={}, firstName={}, lastName={}",
                facebookUserEs.getPhoneNumber(), facebookUserEs.getWorkPlace(),
                facebookUserEs.getWorkplaceCity(), facebookUserEs.getBirthPlace(),
                facebookUserEs.getContactMethod(), facebookUserEs.getFullName(),
                facebookUserEs.getFirstName(), facebookUserEs.getLastName());

        EsSearchRequest esSearchRequest = new EsSearchRequest();
        BoolQueryBuilder bq = new BoolQueryBuilder();

        searchEs(facebookUserEs, bq);
        esSearchRequest.setBq(bq);
        esSearchRequest.setFields(EsFacebookFields.FIELD_QUERY);
        esSearchRequest.setFrom(facebookUserEs.getPages());
        esSearchRequest.setSize(facebookUserEs.getSize());
        esSearchRequest.setNeedScroll(false);

        log.debug("最终FacebookES查询条件: {}, from={}, size={}, sort={}:{}", bq, facebookUserEs.getPages(), facebookUserEs.getSize(),
                EsFacebookFields.SORT_FIELD_PRIMARY, EsFacebookFields.SORT_ORDER_NEWEST_FIRST);
        return esSearchRequest;
    }

    private static void searchEs(FacebookUserEs facebookUserEs, BoolQueryBuilder bq) {
        if (facebookUserEs.getFirstName() != null && !facebookUserEs.getFirstName().isEmpty()) {
            TermQueryBuilder firstNameQuery = QueryBuilders.termQuery(
                    EsFacebookFields.FIRST_NAME,
                    facebookUserEs.getFirstName()
            );
            bq.should(firstNameQuery);
        }


        if (facebookUserEs.getLastName() != null && !facebookUserEs.getLastName().isEmpty()) {
            TermQueryBuilder lastNameQuery = QueryBuilders.termQuery(
                    EsFacebookFields.LAST_NAME,
                    facebookUserEs.getLastName()
            );
            bq.should(lastNameQuery);
        }

        if (facebookUserEs.getFullName() != null && !facebookUserEs.getFullName().isEmpty()) {
            TermQueryBuilder fullNameQuery = QueryBuilders.termQuery(
                    EsFacebookFields.FULL_NAME + ".keyword",
                    facebookUserEs.getFullName()
            ).boost(2);  // 保持原有的权重提升
            bq.should(fullNameQuery);
        }

        // 工作地点多值查询支持
        if (facebookUserEs.getWorkPlace() != null && !facebookUserEs.getWorkPlace().isEmpty()) {
            BoolQueryBuilder workPlaceBool = QueryBuilders.boolQuery();
            workPlaceBool.should(QueryBuilders.termQuery(
                    EsFacebookFields.WORK_PLACE + ".keyword",
                    facebookUserEs.getWorkPlace()
            ));
            bq.should(workPlaceBool);
        }

        if (facebookUserEs.getContactMethod() != null &&
                !facebookUserEs.getContactMethod().isEmpty()) {

            String contactMethod = facebookUserEs.getContactMethod();

            if (contactMethod.equals("email")) {
                BoolQueryBuilder emailQuery = QueryBuilders.boolQuery()
                        .must(QueryBuilders.existsQuery(EsFacebookFields.EMAIL))
                        .mustNot(QueryBuilders.termQuery(EsFacebookFields.EMAIL, ""))
                        .must(QueryBuilders.wildcardQuery(EsFacebookFields.EMAIL, "*@*"));
                bq.must(emailQuery);
            } else if (contactMethod.equals("phone")) {
                // 检查phone_number字段存在且不为空
                BoolQueryBuilder phoneQuery = QueryBuilders.boolQuery()
                        .must(QueryBuilders.existsQuery(EsFacebookFields.PHONE_NUMBER))
                        .mustNot(QueryBuilders.termQuery(EsFacebookFields.PHONE_NUMBER, ""));
                bq.must(phoneQuery);
            }
        }
        // 设置至少匹配一个should条件（除非有must条件）
        bq.minimumShouldMatch(1);
    }

    /**
     * 构建导出查询的ES查询条件
     *
     * @param queryDTO 查询条件DTO
     * @return BoolQueryBuilder
     */
    private BoolQueryBuilder buildExportQuery(com.shlh.saas.model.dto.FacebookQueryDTO queryDTO) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        // 电话号码查询
        if (queryDTO.getPhoneNumber() != null && !queryDTO.getPhoneNumber().trim().isEmpty()) {
            boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.PHONE_NUMBER, queryDTO.getPhoneNumber()));
        }

        // Facebook ID查询
        if (queryDTO.getFacebookId() != null && !queryDTO.getFacebookId().trim().isEmpty()) {
            boolQuery.must(QueryBuilders.termQuery(EsFacebookFields.UID, queryDTO.getFacebookId()));
        }

        // 名字查询
        if (queryDTO.getFirstName() != null && !queryDTO.getFirstName().trim().isEmpty()) {
            boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.FIRST_NAME, queryDTO.getFirstName()));
        }

        // 姓氏查询
        if (queryDTO.getLastName() != null && !queryDTO.getLastName().trim().isEmpty()) {
            boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.LAST_NAME, queryDTO.getLastName()));
        }

        // 全名查询（同时匹配firstName和lastName）
        if (queryDTO.getName() != null && !queryDTO.getName().trim().isEmpty()) {
            boolQuery.must(QueryBuilders.matchPhraseQuery(EsFacebookFields.FULL_NAME, queryDTO.getName()));
        }

        // 邮箱查询
        if (queryDTO.getEmail() != null && !queryDTO.getEmail().trim().isEmpty()) {
            boolQuery.must(QueryBuilders.termQuery(EsFacebookFields.EMAIL, queryDTO.getEmail().toLowerCase()));
        }

        // 性别查询
        if (queryDTO.getGender() != null && !queryDTO.getGender().trim().isEmpty()) {
            boolQuery.must(QueryBuilders.matchQuery(EsFacebookFields.GENDER, queryDTO.getGender()));
        }

        // 当前所在地多值查询支持
        if (queryDTO.getCurrentLocation() != null && !queryDTO.getCurrentLocation().trim().isEmpty()) {
            BoolQueryBuilder currentLocationQuery = buildMultiValueQuery(
                    queryDTO.getCurrentLocation().trim(),
                    EsFacebookFields.WORKPLACE_CITY,
                    "当前所在地"
            );
            boolQuery.must(currentLocationQuery);
        }

        // 家乡多值查询支持
        if (queryDTO.getHometown() != null && !queryDTO.getHometown().trim().isEmpty()) {
            BoolQueryBuilder hometownQuery = buildMultiValueQuery(
                    queryDTO.getHometown().trim(),
                    EsFacebookFields.BIRTH_PLACE,
                    "家乡"
            );
            boolQuery.must(hometownQuery);
        }

        // 工作地点多值查询支持
        if (queryDTO.getWorkplace() != null && !queryDTO.getWorkplace().trim().isEmpty()) {
            BoolQueryBuilder workplaceQuery = buildMultiValueQuery(
                    queryDTO.getWorkplace().trim(),
                    EsFacebookFields.WORK_PLACE,
                    "工作地点"
            );
            boolQuery.must(workplaceQuery);
        }

        // 关系状态多值查询支持
        if (queryDTO.getRelationshipStatus() != null && !queryDTO.getRelationshipStatus().trim().isEmpty()) {
            BoolQueryBuilder relationshipStatusQuery = buildMultiValueQuery(
                    queryDTO.getRelationshipStatus().trim(),
                    EsFacebookFields.MARITAL_STATUS,
                    "关系状态"
            );
            boolQuery.must(relationshipStatusQuery);
        }

        // 所在地查询（兼容旧代码，同时匹配currentLocation和hometown）- 支持多值查询
        if (queryDTO.getLocation() != null && !queryDTO.getLocation().trim().isEmpty()) {
            BoolQueryBuilder locationQuery = QueryBuilders.boolQuery();

            // 为当前所在地和家乡都添加多值查询支持
            BoolQueryBuilder currentLocationQuery = buildMultiValueQuery(
                    queryDTO.getLocation().trim(),
                    EsFacebookFields.WORKPLACE_CITY,
                    "所在地(当前位置)"
            );
            BoolQueryBuilder hometownQuery = buildMultiValueQuery(
                    queryDTO.getLocation().trim(),
                    EsFacebookFields.BIRTH_PLACE,
                    "所在地(家乡)"
            );

            locationQuery.should(currentLocationQuery);
            locationQuery.should(hometownQuery);
            boolQuery.must(locationQuery);
        }

        // 联系方式筛选
        if (queryDTO.getContactMethod() != null &&
                !queryDTO.getContactMethod().trim().isEmpty() &&
                !queryDTO.getContactMethod().equals("any")) {

            String contactMethod = queryDTO.getContactMethod();
            log.debug("处理联系方式筛选: {}", contactMethod);

            if (contactMethod.equals("email")) {
                // 检查email字段存在且不为空，并且包含@符号
                BoolQueryBuilder emailQuery = QueryBuilders.boolQuery()
                        .must(QueryBuilders.existsQuery(EsFacebookFields.EMAIL))
                        .mustNot(QueryBuilders.termQuery(EsFacebookFields.EMAIL, ""))
                        .must(QueryBuilders.wildcardQuery(EsFacebookFields.EMAIL, "*@*"));
                boolQuery.must(emailQuery);
            } else if (contactMethod.equals("phone")) {
                // 检查phone_number字段存在且不为空
                BoolQueryBuilder phoneQuery = QueryBuilders.boolQuery()
                        .must(QueryBuilders.existsQuery(EsFacebookFields.PHONE_NUMBER))
                        .mustNot(QueryBuilders.termQuery(EsFacebookFields.PHONE_NUMBER, ""));
                boolQuery.must(phoneQuery);
            }
        }

        // 数据库表名筛选
        if (queryDTO.getMysqlTable() != null && !queryDTO.getMysqlTable().trim().isEmpty()) {
            boolQuery.must(QueryBuilders.termQuery(EsFacebookFields.MYSQL_TABLE, queryDTO.getMysqlTable()));
        }

        log.debug("构建导出查询条件: {}", boolQuery.toString());
        return boolQuery;
    }

    /**
     * 执行ES查询并返回标识信息（支持分页）
     *
     * @param boolQuery 布尔查询条件
     * @param from      起始位置
     * @param size      查询数量
     * @return 包含mysqlTable和id的结果列表
     */
    private List<Map<String, String>> executeEsSearchForIdentifiersWithPagination(BoolQueryBuilder boolQuery, int from, int size) {
        List<Map<String, String>> results = new ArrayList<>();

        try {
            // 创建ES搜索请求
            EsSearchRequest esSearchRequest = new EsSearchRequest();
            esSearchRequest.setBq(boolQuery);
            esSearchRequest.setFrom((long) from);
            esSearchRequest.setSize((long) size);
            esSearchRequest.setNeedScroll(false);

            // 添加排序规则，确保与分页查询一致
            esSearchRequest.setSortName(EsFacebookFields.SORT_FIELD_PRIMARY);
            esSearchRequest.setSortOrder(EsFacebookFields.SORT_ORDER_NEWEST_FIRST);

            // 只查询必要的字段以提升性能
            String[] fields = {EsFacebookFields.MYSQL_TABLE, EsFacebookFields.MYSQL_ID};
            esSearchRequest.setFields(fields);

            log.debug("执行ES分页查询，条件: {}, from: {}, size: {}, sort: {}:{}", boolQuery.toString(), from, size,
                    EsFacebookFields.SORT_FIELD_PRIMARY, EsFacebookFields.SORT_ORDER_NEWEST_FIRST);

            // 执行查询
            SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

            if (searchResponse == null) {
                log.warn("ES分页查询返回null响应");
                return results;
            }

            SearchHits searchHits = searchResponse.getHits();
            if (searchHits == null || searchHits.getHits() == null) {
                log.warn("ES分页查询返回空结果");
                return results;
            }

            SearchHit[] hits = searchHits.getHits();
            log.info("ES分页查询返回{}条匹配记录", hits.length);

            // 提取标识信息
            for (SearchHit hit : hits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                if (sourceAsMap != null) {
                    Map<String, String> identifier = new HashMap<>();
                    identifier.put("mysqlTable", getStringSafely(sourceAsMap, EsFacebookFields.MYSQL_TABLE));
                    identifier.put("id", getStringSafely(sourceAsMap, EsFacebookFields.MYSQL_ID));

                    // 验证标识信息完整性
                    if (identifier.get("mysqlTable") != null && identifier.get("id") != null) {
                        results.add(identifier);
                    }
                }
            }

            log.info("ES分页查询完成，有效匹配记录数: {}", results.size());
            return results;

        } catch (Exception e) {
            log.error("执行ES分页查询失败: {}", e.getMessage(), e);
            return results;
        }
    }

    /**
     * 执行ES计数查询
     *
     * @param boolQuery 布尔查询条件
     * @return 匹配记录总数
     */
    private long executeEsCountQuery(BoolQueryBuilder boolQuery) {
        try {
            // 创建ES搜索请求（只查询计数）
            EsSearchRequest esSearchRequest = new EsSearchRequest();
            esSearchRequest.setBq(boolQuery);
            esSearchRequest.setFrom(0L);
            esSearchRequest.setSize(0L); // 只查询计数，不返回具体记录
            esSearchRequest.setNeedScroll(false);
            esSearchRequest.setTrackTotalHits(true);

            log.debug("执行ES计数查询，条件: {}", boolQuery.toString());

            // 执行查询
            SearchResponse searchResponse = EsRestClient.searchWithTermQuery(getEsIndexInfo(), esSearchRequest);

            if (searchResponse == null) {
                log.warn("ES计数查询返回null响应");
                return 0;
            }

            SearchHits searchHits = searchResponse.getHits();
            if (searchHits == null) {
                log.warn("ES计数查询返回空结果");
                return 0;
            }

            long totalCount = searchHits.getTotalHits().value;
            log.info("ES计数查询完成，匹配记录总数: {}", totalCount);

            return totalCount;

        } catch (Exception e) {
            log.error("执行ES计数查询失败: {}", e.getMessage(), e);
            return 0;
        }
    }

    /**
     * 构建多值查询条件
     *
     * @param fieldValue 字段值（可能包含中文顿号分隔的多个值）
     * @param fieldName  ES字段名
     * @param fieldDesc  字段描述（用于日志）
     * @return BoolQueryBuilder 查询构建器
     */
    private BoolQueryBuilder buildMultiValueQuery(String fieldValue, String fieldName, String fieldDesc) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

        if (fieldValue.contains("、")) {
            // 多值查询：使用OR逻辑
            String[] values = fieldValue.split("、");
            queryBuilder.minimumShouldMatch(1);

            log.info("🔍 {}多值查询: 原始值={}, 拆分后={}", fieldDesc, fieldValue, String.join(",", values));

            for (String value : values) {
                String trimmedValue = value.trim();
                if (!trimmedValue.isEmpty()) {
                    MatchQueryBuilder valueQuery = QueryBuilders.matchQuery(fieldName, trimmedValue);
                    queryBuilder.should(valueQuery);
                    log.debug("🔍 添加{}查询条件: {}", fieldDesc, trimmedValue);
                }
            }
        } else {
            // 单值查询
            MatchQueryBuilder valueQuery = QueryBuilders.matchQuery(fieldName, fieldValue);
            queryBuilder.should(valueQuery);
            log.info("🔍 {}单值查询: {}", fieldDesc, fieldValue);
        }

        return queryBuilder;
    }

}
